from os import error
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from test2 import scaleOut, randomFrag

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

PRESET_FIELDS = [  # 'A项电流','A相电压','B项电流','B项电压','C项电流', 'C项电压','功率因数','运行状态'
    '出口压力', '进口压力', '瞬时流量', '泵前轴温度', '泵后轴温度', '周波', '润滑油压力',
    '有功功率', '无功功率', '前轴承温度', '后轴承温度', '定子温度', '电机冷却水压力',
    '定子前部温度', '定子中部温度', '定子后部温度', '视在功率', ]


def randomSeam2(data, M, NRan, warnFacRan=[0.1, 0.9], errorProb=0.3, warnProb=0.6, noise=False):
    """[从data中随机取多段数据进行缝合，缝合时后一段数据会偏移到前一段数据的尾部]

    Args:
        data ([numpy array]): [包含多列数据，用于缝合的参考数据]
        M ([int]): [决定取多少段数据进行缝合]
        NRan ([list]): [列表包含两个整型数，表示每一段数据的随机长度范围]
        warnFacRan (list, optional): [列表包含两个数，表示预警系数,如[0.1,0.9] ]. Defaults to [0.1,0.9].
        errorProb (float, optional): [模拟错误的概率]. Defaults to 0.2.
        warnProb (float, optional): [模拟预警的概率]. Defaults to 0.5.
        noise (bool, optional): [是否添加噪声]. Defaults to False.

    Returns:
        [numpy array]: [缝合得到的数据]
    """
    idxRan = [0, data.shape[0]]
    idxFrags = randomFrag(idxRan, M, NRan)
    col = data.shape[1]
    seamData=[]
    for i in range(col):
        colData = data[:, i]
        errorRan = [np.nanmin(colData), np.nanmax(colData)]
        errorDiff = errorRan[1] - errorRan[0]
        seamColData = np.array([])
        lastTail = colData[idxFrags[0][0]:idxFrags[0][1]][-1]
        for frag in idxFrags:
            sub = colData[frag[0]:frag[1]].copy()#此处必须copy，否则后面的代码会修改原数组
            head = sub[0]
            diff = head - lastTail
            sub -= diff
            max = np.nanmax(sub)
            min = np.nanmin(sub)
            if noise:
                r = max - min
                sub += np.random.uniform(-0.05, 0.05, size=sub.shape) * r
            seamColData = np.append(seamColData, sub)
            lastTail = sub[-1]
        seamColData = (seamColData - np.nanmin(seamColData)) / (np.nanmax(seamColData) - np.nanmin(seamColData))  # 归一化
        seamColData = seamColData * errorDiff + errorRan[0]  # 参照errorRan反归一化
        seamData = np.append(seamData,seamColData)
    seamData.resize((col,seamData.shape[0]//col))
    seamData = seamData.transpose()
    for i in range(col):
        colData = data[:, i]
        errorRan = [np.nanmin(colData), np.nanmax(colData)]
        errorDiff = errorRan[1] - errorRan[0]
        warnRan = [errorDiff * warnFacRan[0] + errorRan[0], errorDiff * warnFacRan[1] + errorRan[0]]
        warnDiff = warnRan[1] - warnRan[0]
        error8 = errorDiff * 0.8 + errorRan[0]
        error2 = errorDiff * 0.2 + errorRan[0]
        warn8 = warnDiff * 0.8 + warnRan[0]
        warn2 = warnDiff * 0.2 + warnRan[0]
        left = 0
        e = errorDiff * 0.05
        w = warnDiff * 0.05
        for frag in idxFrags:
            right = left + frag[1] - frag[0]
            sub = seamData[:,i][left:right]
            min = np.nanmin(sub)
            max = np.nanmax(sub)
            diff = max - min
            rand = np.random.random()
            # 除了满足概率条件，还需实现满足这一段的数据接近于错误限制且这一段的数据有明显起伏，避免中间段平缓突然被模拟为错误
            if rand < errorProb and diff > e and (min < error2 or max > error8):
                sub = scaleOut(sub, errorRan, np.random.uniform(0.05, 0.2))
                seamData[:,i][left:right] = sub
            elif rand < warnProb and diff > w and (min < warn2 or max > warn8):
                sub = scaleOut(sub, warnRan, np.random.uniform(0.05, 0.2))
                seamData[:,i][left:right] = sub
            else:
                pass
            left = right
    return seamData


if __name__ == "__main__":
    # np.random.seed(3)
    filePath = '../data/一号泵.csv'
    data = pd.read_csv(filePath, encoding="utf-8")
    data = data[['出口压力', '进口压力', '瞬时流量']]#data[PRESET_FIELDS]
    data = data.values
    simData = randomSeam2(data, 500, [100, 200])

    x=[i for i in range(simData.shape[0])]
    for i in range(simData.shape[1]):
        plt.figure()
        plt.plot(x,simData[:,i])
        max=np.nanmax(data[:, i])
        min=np.nanmin(data[:, i])
        ran=max-min
        print(ran*0.1+min,ran*0.9+min)
        plt.axhline(max)
        plt.axhline(min)
    plt.show()

    # df=pd.DataFrame(simData,columns=PRESET_FIELDS)
    # for field in PRESET_FIELDS:
    #     min = df[field].min()
    #     max = df[field].max()
    #     ran = max - min
    #     df[field] = df[field].map(lambda x: (x - min) / ran)
    # df.plot()
    # plt.show()
